<?php

namespace apiend\models;

use Yii;
use common\helpers\ArrayHelper;
use common\helpers\StringHelper;
use common\rbac\rules\PolicyRule;
use common\models\admin\AdminCompany;

/**
 * 账号信息
 * @author emhome <emhome@163.com>
 * @since 1.0
 */
class User extends \common\models\BaseUser {

    /**
     * @inheritdoc
     */
    public $token;

    /**
     * @inheritdoc
     */
    public function attributeLabels() {
        return [
            'id' => 'ID',
            'username' => '用户名',
            'mobile' => 'Mobile',
            'email' => 'Email',
            'avatar' => '头像',
            'cover' => '头像',
            'auth_key' => 'Auth Key',
            'password_hash' => 'Password Hash',
            'password_reset_token' => 'Password Reset Token',
            'ip' => 'Ip',
            'status' => 'Status',
            'created_at' => 'Created At',
            'updated_at' => 'Updated At',
            'deleted_at' => 'Deleted At',
            'profiles' => 'PROFILES',
        ];
    }

    /**
     * @inheritdoc
     */
    public function getRuleData() {
        $manager = Yii::$app->getAuthManager();
        $roles = $manager->getRolesByUser($this->id);
        $authData = [];
        foreach ($roles as $role) {
            if (!$role->ruleName) {
                continue;
            }
            $rule = $manager->getRule($role->ruleName);
            if ($rule instanceof PolicyRule) {
                $authData = ArrayHelper::merge($authData, $role->data);
            }
        }
        return $authData;
    }

    /**
     * @inheritdoc
     */
    public function hasElementRule($element) {
        $manager = Yii::$app->getAuthManager();
        $roles = $manager->getRolesByUser($this->id);
        foreach ($roles as $role) {
            if (!$role->ruleName || $role->ruleName !== $element) {
                continue;
            }
            $rule = $manager->getRule($role->ruleName);
            if ($rule instanceof PolicyRule) {
                return true;
            }
        }
        return false;
    }

    /**
     * @inheritdoc
     */
    public function getRuleElements($name = null, $default = null) {
        $data = $this->ruleData;
        if (empty($data)) {
            return $default;
        }
        if ($name) {
            return ArrayHelper::getValue($data, $name, $default);
        }
        return $data;
    }

    /**
     * @inheritdoc
     */
    public function unionCompanyRules($element = 'company') {
        $storeIds = $this->getRuleElements($element, []);
        $storeIds[] = $this->getStoreId();
        return array_filter($storeIds);
    }

    /**
     * @param string $value
     * @param mixed $msg
     * @param mixed $element
     */
    public function checkRuleElementStore($value, $msg = false, $element = 'company') {
        $data = $this->unionCompanyRules($element);
        if (empty($data)) {
            return false;
        }
        $authent = ArrayHelper::isIn($value, $data);
        if ($msg !== false && !$authent) {
            throw new \yii\web\ForbiddenHttpException($msg ?: Yii::t('message', 'Forbidden ' . $element));
        }
        return $authent;
    }

    /**
     * @param \yii\db\Query $query
     * @param string $attribute
     * @param string $element
     */
    public function fillRuleCondition(&$query, $attribute, $element) {
        $data = $this->unionCompanyRules($element);
        $query->andWhere([
            $attribute => $data
        ]);
    }

    /**
     * @param string $element
     * @param mixed $value
     * @param mixed $msg
     */
    public function checkRuleElement($element, $value, $msg = null) {
        $data = $this->getRuleElements($element);
        if (!$data) {
            return true;
        }
        $authent = ArrayHelper::isIn($value, $data);
        if ($msg !== false && !$authent) {
            throw new \yii\web\ForbiddenHttpException($msg ?: Yii::t('message', 'Forbidden ' . $element));
        }
        return $authent;
    }

    public function getIsFounder() {
        $fouder = ArrayHelper::getValue(Yii::$app->params, 'founder.username');
        if ($fouder && $this->username == $fouder) {
            return true;
        }
        return false;
    }

    public function getIsAdmin() {
        $roles = $this->getRoles();
        return in_array('admin', $roles);
    }

    public function getRoles() {
        $manager = Yii::$app->getAuthManager();
        $userRoles = $manager->getRolesByUser($this->id);
        $roles = array_keys($userRoles);
        if ($this->appUser) {
            $roles[] = 'manager';
        }
        return $roles;
    }

    public function getAuthRoles() {
        $manager = Yii::$app->getAuthManager();
        $userRoles = $manager->getRolesByUser($this->id);
        return array_keys($userRoles);
    }

    public function getCompany() {
        return $this->hasOne(AdminCompany::class, ['id' => 'company_id']);
    }

    public function getAppUser() {
        return $this->hasOne(\common\models\user\User::class, ['admin_id' => 'id']);
    }

    public function getCompanyId() {
        return $this->company_id;
    }

    public function getCompanys() {
        return $this->hasMany(AdminCompany::class, ['parent_id' => 'company_id']);
    }

    public function getCompanyIds() {
        $companys = ArrayHelper::getLeafs($this->companys);
        if ($this->company_id) {
            $companys[] = $this->company_id;
        }
        return $companys;
    }

    public function getAuthMenus() {
        return [];
        return SiteAuthMenu::routers($this->getRoles(), $this->companyId);
    }

    public function getMaskMobile() {
        return StringHelper::maskChar($this->mobile);
    }

    /**
     * 保存请求时的UNIX时间戳
     * @return type
     */
    public function logout() {
        $this->removeAccessToken();
        if (!$this->save()) {
            $this->dumpError('退出失败时帐号信息出现异常，请检查帐号安全日志');
        }
        return Yii::$app->user->logout();
    }

    public function fields() {
        return [
            'id',
            'name' => 'username',
            'mobile' => 'maskMobile',
            'avatar' => 'portrait',
            'introduction' => 'profile',
            'company_id',
            'company',
            'status',
            'roles',
            'menus' => 'authMenus',
            'created_at',
        ];
    }

}
